import re
from django.contrib.gis.db.models import GeometryField
from django.contrib.gis.gdal.error import OGRIndexError
from django.contrib.gis.gdal import * 
from django.contrib.gis.models import SpatialRefSys
from core.models import *

# Regex to help parse district strings.
DISTRICT_REG = re.compile('\d\d?')

class SHPReader(object):

    def __init__(self, shp_path, srid, boundary_type, district_key, 
                 boundary_class):
        self.layer = DataSource(shp_path)[0]
        self.srid = self.get_srid(srid)
        self.bnd_type = boundary_type
        self.dist_key = district_key
        self.bnd_class = boundary_class

    def get_srid(self, srid):
        """
        Return an integer for srid.
        """
        return int(srid)

    def get_district(self, feat, key=None):
        """
        Return an integer for the district value given a feature.
        """
        if not key:
            key = self.dist_key
        try:
            return int(feat.get(key))
        except ValueError:
            # District is not an integer. Try to parse things 
            # like "12th District".
            print "Trying to parse %s" % feat.get(key)
            return self.parse_district(feat.get(key))

class ChicagoSHPReader(SHPReader):
    """
    Chicago
    """
    
    def get_zip_file(self):
        return 'http://someurl.com/file.zip'


class SFBaySHPReader(SHPReader):
    """
    Bay Area
    """

    def get_state_abbr(self):
        """Return string for state abbreviation."""
        return 'CA'

    def parse_district(self, value):
        """
        Return a int given an odd string value for district or None.
        """
        if not value:
            print "District value is %s empty" % value
            return None
        else:
            match = DISTRICT_REG.search(value)
            if match:
                return int(match.group())
        return None 
            

class NYSHPReader(SHPReader):
    """
    New York
    """

    def get_state_abbr(self):
        return 'NY'

def import_shp(shp_reader):
    """
    SHPReader requires a shape file and SRID.  You can determine the SRID by 
    going to spatialreference.org and look it up according to the SRS header.

    In [1]: from django.contrib.gis.gdal import *

    In [2]: ds = DataSource('nyad.shp')

    In [3]: sr1 = ds[0].srs

    In [4]: print sr1
    PROJCS["NAD_1983_StatePlane_New_York_Long_Island_FIPS_3104_Feet",
        GEOGCS["GCS_North_American_1983",
            DATUM["North_American_Datum_1983",
                SPHEROID["GRS_1980",6378137.0,298.257222101]],
            PRIMEM["Greenwich",0.0],
            UNIT["Degree",0.0174532925199433]],
        PROJECTION["Lambert_Conformal_Conic_2SP"],
        PARAMETER["False_Easting",984250.0],
        PARAMETER["False_Northing",0.0],
        PARAMETER["Central_Meridian",-74.0],
        PARAMETER["Standard_Parallel_1",40.66666666666666],
        PARAMETER["Standard_Parallel_2",41.03333333333333],
        PARAMETER["Latitude_Of_Origin",40.16666666666666],
        UNIT["Foot_US",0.3048006096012192]]

    # Now go do a search on spatialreference.org for "new york long island" and
    # check to see which proj4 strings match closest.

    In [5]: sr2 = SpatialReference(2263)

    In [6]: print sr1.proj4
    ------> print(sr1.proj4)
    +proj=lcc +lat_1=40.66666666666666 +lat_2=41.03333333333333 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs 

    In [7]: print sr2.proj4
    ------> print(sr2.proj4)
    +proj=lcc +lat_1=41.03333333333333 +lat_2=40.66666666666666 +lat_0=40.16666666666666 +lon_0=-74 +x_0=300000.0000000001 +y_0=0 +ellps=GRS80 +datum=NAD83 +to_meter=0.3048006096012192 +no_defs 
    """

    for feat in shp_reader.layer:
        boundary=shp_reader.bnd_class(
            district = shp_reader.get_district(feat),
            state = shp_reader.get_state_abbr(),
            bnd_type = shp_reader.bnd_type )
        boundary.geom = feat.geom.wkt
        boundary.geom.srid = shp_reader.srid
        #, srid=shp_reader.srid)
        boundary.save()

